package com.ruoyi.recipes.task;

import com.ruoyi.recipes.mapper.RecipesMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 评论数据同步定时任务
 * 
 * @author syy
 * @date 2025-01-27
 */
@Component
public class CommentSyncTask {
    
    private static final Logger log = LoggerFactory.getLogger(CommentSyncTask.class);
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    
    @Resource
    private RecipesMapper recipesMapper;
    
    // Redis Key 前缀
    private static final String COMMENT_LIKE_COUNT_KEY_PREFIX = "comment:like_count:";
    
    /**
     * 每5分钟同步一次评论点赞数据到数据库
     */
    @Scheduled(fixedRate = 300000) // 5分钟 = 300000毫秒
    public void syncCommentLikeCount() {
        log.info("开始同步评论点赞数据到数据库...");
        
        try {
            // 获取所有评论点赞数key
            Set<String> keys = redisTemplate.keys(COMMENT_LIKE_COUNT_KEY_PREFIX + "*");
            
            if (keys != null && !keys.isEmpty()) {
                int syncCount = 0;
                
                for (String key : keys) {
                    try {
                        // 从key中提取评论ID
                        String commentIdStr = key.substring(COMMENT_LIKE_COUNT_KEY_PREFIX.length());
                        Long commentId = Long.valueOf(commentIdStr);
                        
                        // 获取Redis中的点赞数
                        Object likeCountObj = redisTemplate.opsForValue().get(key);
                        if (likeCountObj != null) {
                            Long likeCount;
                            
                            // 处理类型转换
                            if (likeCountObj instanceof Integer) {
                                likeCount = ((Integer) likeCountObj).longValue();
                            } else if (likeCountObj instanceof Long) {
                                likeCount = (Long) likeCountObj;
                            } else {
                                likeCount = Long.valueOf(likeCountObj.toString());
                            }
                            
                            // 更新数据库
                            int result = recipesMapper.updateCommentLikeCount(commentId, likeCount);
                            if (result > 0) {
                                syncCount++;
                                log.debug("同步评论ID: {} 点赞数: {} 到数据库成功", commentId, likeCount);
                            }
                        }
                    } catch (Exception e) {
                        log.error("同步评论点赞数据失败，key: {}, 错误: {}", key, e.getMessage());
                    }
                }
                
                log.info("评论点赞数据同步完成，共同步 {} 条记录", syncCount);
            } else {
                log.info("没有需要同步的评论点赞数据");
            }
            
        } catch (Exception e) {
            log.error("同步评论点赞数据时发生异常", e);
        }
    }
    
    /**
     * 每10分钟同步一次Redis点赞记录到数据库
     */
    @Scheduled(fixedRate = 600000) // 10分钟 = 600000毫秒
    public void syncCommentLikeRecords() {
        log.info("开始同步评论点赞记录到数据库...");
        
        try {
            // 获取所有评论点赞用户key
            Set<String> keys = redisTemplate.keys("comment:like:*");
            
            if (keys != null && !keys.isEmpty()) {
                int syncCount = 0;
                
                for (String key : keys) {
                    try {
                        // 从key中提取评论ID
                        String commentIdStr = key.substring("comment:like:".length());
                        Long commentId = Long.valueOf(commentIdStr);
                        
                        // 获取Redis中的点赞用户集合
                        Set<Object> userIds = redisTemplate.opsForSet().members(key);
                        if (userIds != null && !userIds.isEmpty()) {
                            for (Object userIdObj : userIds) {
                                if (userIdObj != null) {
                                    Long userId = Long.valueOf(userIdObj.toString());
                                    
                                    // 检查数据库中是否已存在该点赞记录
                                    int existingCount = recipesMapper.checkCommentLike(commentId, userId);
                                    if (existingCount == 0) {
                                        // 插入点赞记录
                                        int result = recipesMapper.insertCommentLike(commentId, userId);
                                        if (result > 0) {
                                            syncCount++;
                                            log.debug("同步点赞记录成功，commentId: {}, userId: {}", commentId, userId);
                                        }
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("同步评论点赞记录失败，key: {}, 错误: {}", key, e.getMessage());
                    }
                }
                
                log.info("评论点赞记录同步完成，共同步 {} 条记录", syncCount);
            } else {
                log.info("没有需要同步的评论点赞记录");
            }
            
        } catch (Exception e) {
            log.error("同步评论点赞记录时发生异常", e);
        }
    }
    
    /**
     * 每天凌晨2点清理过期的Redis数据
     */
    @Scheduled(cron = "0 0 2 * * ?")
    public void cleanExpiredRedisData() {
        log.info("开始清理过期的Redis评论数据...");
        
        try {
            // 清理过期的评论点赞数数据（保留7天）
            Set<String> likeCountKeys = redisTemplate.keys(COMMENT_LIKE_COUNT_KEY_PREFIX + "*");
            if (likeCountKeys != null) {
                for (String key : likeCountKeys) {
                    // 检查key是否存在，如果不存在会自动清理
                    if (Boolean.FALSE.equals(redisTemplate.hasKey(key))) {
                        redisTemplate.delete(key);
                    }
                }
            }
            
            log.info("Redis评论数据清理完成");
            
        } catch (Exception e) {
            log.error("清理Redis评论数据时发生异常", e);
        }
    }
}
